package com.factory.aiclient.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.factory.aiclient.feign.*;
import com.factory.aiclient.pojo.*;
import com.factory.aiclient.service.AlgorithmService;
import com.factory.aiclient.service.DeviceService;
import com.factory.aiclient.service.UserDeviceService;
import com.factory.common.bean.*;
import com.factory.common.constant.DeviceConstant;
import com.factory.common.constant.SyncConstant;
import com.factory.common.pojo.Result;
import com.factory.common.utils.DateUtil;
import com.factory.common.utils.ImgUtil;
import com.factory.common.utils.StringUtil;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;

/**
 * 数据同步控制器
 *
 * @author JW
 * @version 1.0
 * @date 2020/10/26 10:19
 */
@RestController
@RequestMapping("/aiclient/sync")
@Slf4j
public class SyncController {

    @Autowired
    private CustomersClient customersClient;

    @Autowired
    private MemberClient memberClient;

    @Autowired
    private MemberFaceClient memberFaceClient;

    @Autowired
    private CameraClient cameraClient;

    @Autowired
    private AlarmClient alarmClient;

    @Autowired
    private FaceCapturedClient faceCapturedClient;

    @Autowired
    private AlgorithmService algorithmService;

    @Autowired
    private CustomersDoorwayClient customersDoorwayClient;

    @Autowired
    private SpeechClient speechClient;

    @Value("${jiexun.upload.dir}")
    private String upload;


    /**
     * 客流数据表数据同步接口
     *
     * @param syncListPojo
     * @return
     */
    @PostMapping("/customers")
    public Result customers(HttpServletRequest request, @RequestBody SyncListPojo<CustomersPojo> syncListPojo) {
        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }

        log.info("客流数据表数据同步接口,{}", current.getId());

        List<CustomersPojo> customers = syncListPojo.getData();
        List<Customers> customersItem = new ArrayList<>();

        for (CustomersPojo e : customers) {
            if (StringUtil.isEmpty(e.getId())) {
                return Result.fail(JSON.toJSONString(e) + "的id不能为空!");
            } else if (StringUtil.isEmpty(e.getMemberFaceId())) {
                return Result.fail(JSON.toJSONString(e) + "的member face id不能为空!");
            } else if (StringUtil.isEmpty(e.getCreateDate())) {
                return Result.fail(JSON.toJSONString(e) + "的createDate不能为空!");
            }
            if (StringUtil.isEmpty(e.getAge())) {
                e.setAge(2);
            }
            if (StringUtil.isEmpty(e.getGender())) {
                e.setGender(-1);
            }
            if (StringUtil.isEmpty(e.getCustomersType())) {
                e.setCustomersType(-1);
            }
            e.setDeviceId(current.getId());
            e.setDeviceName(current.getName());
            e.setUserId(current.getUserId());
            e.setUserName(current.getUserName());
            e.setLocationId(current.getLocationId());
            e.setLocationName(current.getLocationName());
            customersItem.add(e);
        }

        if (!customersItem.isEmpty()) {
            return customersClient.inserts(customersItem);
        }

        return Result.fail("同步失败!");
    }

    /**
     * 客户端同步会员信息数据接口
     *
     * @return
     */
    @PostMapping("/member")
    public Result member(HttpServletRequest request, @RequestBody MemberPojo member) {
        Optional<Result> validate = member.validate();
        if (validate.isPresent()) {
            return validate.get();
        }
        if (StringUtil.isEmpty(member.getId())) {
            return Result.fail("id不能为空");
        }

        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }
        log.info("客户端同步会员信息数据接口,{}", current.getId());

        if (StringUtil.notEmpty(member.getPhoto())) {
            String picturePath = current.getUserId() + File.separator + DateUtil.getDateString(new Date(), "yyyy-MM-dd"), fileName = StringUtil.getUUID() + ".jpg";
            ImgUtil.generateBase64Image(member.getPhoto(), upload + picturePath, fileName);
            member.setPhoto(picturePath + File.separator + fileName);
        }

        switch (member.getMethod()) {
            case 1:

                member.setDeviceId(current.getId());
                member.setDeviceName(current.getName());
                member.setUserId(current.getUserId());
                member.setUserName(current.getName());
                member.setUpdateDate(member.getCreateDate());

                if (null != memberClient.query(member.getId(), current.getId()).getData())
                    return memberClient.update(member, member.getId(), current.getId());
                else
                    return memberClient.insert(member);
            case 2:
                return memberClient.update(member, member.getId(), current.getId());
            case 3:
                return memberClient.delete(member.getId(), current.getId());
        }

        return Result.fail("同步失败!");
    }

    /**
     * 会员的人脸特征值数据同步接口
     *
     * @return
     */
    @PostMapping("/memberFace")
    public Result memberFace(HttpServletRequest request, @RequestBody SyncListPojo<MemberFacePojo> syncListPojo) {

        List<MemberFacePojo> memberFaces = syncListPojo.getData();
        if (null == memberFaces || memberFaces.isEmpty()) {
            return Result.fail("同步数据为空!");
        }

        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }
        log.info("会员的人脸特征值数据同步接口,{}", current.getId());

        List<MemberFace> memberFaceList = new ArrayList<>();
        for (MemberFacePojo memberFace : memberFaces) {
            if (StringUtil.isEmpty(memberFace.getId())) {
                return Result.fail(JSON.toJSONString(memberFace) + "id不能为空");
            }

            memberFace.setImagePath("");
            memberFace.setDeviceId(current.getId());
            memberFace.setDeviceName(current.getName());
            memberFace.setUserId(current.getUserId());
            memberFace.setUserName(current.getUserName());
            memberFace.setLocationId(current.getLocationId());
            memberFace.setLocationName(current.getLocationName());
            memberFaceList.add(memberFace);
        }

        if (!memberFaceList.isEmpty()) {
            return memberFaceClient.inserts(memberFaceList);
        }

        return Result.fail("同步失败!");
    }

    /**
     * 客户端同步摄像头数据接口
     *
     * @return
     */
    @PostMapping("/camera")
    public Result camera(HttpServletRequest request, @RequestBody CameraPojo cameraPojo) {

        Optional<Result> validate = cameraPojo.validate();
        if (validate.isPresent()) {
            return validate.get();
        }

        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }
        log.info("客户端同步摄像头数据接口,{}", current.getId());

        switch (cameraPojo.getMethod()) {
            case 1:
                cameraPojo.setDeviceId(current.getId());
                cameraPojo.setDeviceName(current.getName());
                cameraPojo.setUserId(current.getUserId());
                cameraPojo.setUserName(current.getUserName());
                cameraPojo.setLocationId(current.getLocationId());
                cameraPojo.setLocationName(current.getLocationName());

                if (null != cameraClient.query(cameraPojo.getId(), current.getId()).getData())
                    return cameraClient.update(cameraPojo, cameraPojo.getId(), current.getId());
                else
                    return cameraClient.insert(cameraPojo);
            case 2:
                return cameraClient.update(cameraPojo, cameraPojo.getId(), current.getId());
            case 3:
                return cameraClient.delete(cameraPojo.getId(), current.getId());
        }

        return Result.fail("同步失败!");
    }

    /**
     * 客户端更新摄像头的状态接口
     *
     * @return
     * @Param cameraIds
     * @Param deviceId
     */
    @PostMapping("/updateCameraStatus")
    public Result updateCameraStatus(HttpServletRequest request, @RequestBody Map<String, Object> params) {

        if (StringUtil.isEmpty(params.get("cameraIds"))) {
            return Result.fail("cameraIds不能为空!");
        }

        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }
        log.info("客户端更新摄像头的状态接口,{}", current.getId());

        params.put("deviceId", current.getId());

        return cameraClient.updateStatus(params);
    }

    /**
     * 客户端上报异常告警信息接口
     *
     * @throws
     * @Title: reportSingular
     * @Description:
     * @param: @param conditions
     * @param: @return
     * @return: String
     */
    @ResponseBody
    @PostMapping("/alarm")
    public Result alarm(HttpServletRequest request, @RequestBody JSONObject jsonObject) {

        String cameraId = jsonObject.getString("cameraId");
        if (StringUtil.isEmpty(cameraId)) {
            return Result.fail("cameraId非空");
        }

        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }
        log.info("客户端上报异常告警信息接口,{}", current.getId());

        Result query = cameraClient.query(cameraId, current.getId());
        if (!query.isStatus() || null == query.getData()) {
            return Result.fail("摄像头不存在!");
        }

        Alarm alarm = new Alarm();
        alarm.setId(StringUtil.randomStr(2) + System.currentTimeMillis() / 10);
        alarm.setDeviceId(current.getId());
        alarm.setDeviceName(current.getName());
        alarm.setUserId(current.getUserId());
        alarm.setUserName(current.getName());
        alarm.setLocationName(current.getLocationName());
        alarm.setLocationId(current.getLocationId());
        Camera camera = JSON.parseObject(JSON.toJSONString(query.getData()), Camera.class);
        alarm.setCameraId(camera.getId());
        alarm.setCameraName(camera.getName());
        alarm.setCreateDate(new Date(jsonObject.getLong("createDate")));

        String exceptionDesc = jsonObject.getString("exceptionDesc");
        List<Algorithm> algorithms = algorithmService.selectList(new QueryWrapper<Algorithm>().ge("status", 0));
        for (Algorithm algorithm : algorithms) {
            if (exceptionDesc.indexOf(algorithm.getModel()) != -1) {
                alarm.setType(algorithm.getModel());
                alarm.setName(algorithm.getName());
                alarm.setDescription(algorithm.getAudio());
            }
        }


        String picturePath = File.separator + "alarm" + File.separator + DateUtil.getDateString(new Date(), "yyyy-MM-dd"), fileName = alarm.getId() + ".jpg";
        ImgUtil.generateBase64Image(jsonObject.getString("picture"), upload + picturePath, fileName);
        alarm.setPicture(picturePath + File.separator + fileName);

        alarm.setStatus(2);
        alarmClient.insert(alarm);

        return Result.success();
    }

    /**
     * 客户端抓拍人脸照片上报接口
     *
     * @throws
     * @Title: reportSingular
     * @Description:
     * @param: @param conditions
     * @param: @return
     * @return: String
     */
    @ResponseBody
    @PostMapping("/faceCaptured")
    public Result faceCaptured(HttpServletRequest request, @RequestBody JSONObject jsonObject) {
        String cameraId = jsonObject.getString("cameraId");

        if (StringUtil.isEmpty(cameraId)) {
            return Result.fail("cameraId非空");
        } else if (StringUtil.isEmpty(jsonObject.get("createDate"))) {
            return Result.fail("createDate非空");
        } else if (StringUtil.isEmpty(jsonObject.get("faceImage"))) {
            return Result.fail("faceImage非空");
        }

        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }
        log.info("客户端抓拍人脸照片上报接口,{}", current.getId());

        Result query = cameraClient.query(cameraId, current.getId());
        if (null == query.getData()) {
            return Result.fail("无此摄像头!");
        }

        FaceCaptured faceCaptured = new FaceCaptured();
        faceCaptured.setId(StringUtil.randomStr(2) + System.currentTimeMillis() / 10);
        faceCaptured.setDeviceId(current.getId());
        faceCaptured.setDeviceName(current.getName());
        faceCaptured.setUserId(current.getUserId());
        faceCaptured.setUserName(current.getName());
        faceCaptured.setLocationName(current.getLocationName());
        faceCaptured.setLocationId(current.getLocationId());
        Camera camera = JSON.parseObject(JSON.toJSONString(query.getData()), Camera.class);
        faceCaptured.setCameraId(camera.getId());
        faceCaptured.setCameraName(camera.getName());
        faceCaptured.setFaceId(jsonObject.getString("faceId"));
        faceCaptured.setCreateDate(new Date(jsonObject.getLong("createDate")));

        String faceImagePath = File.separator + "faceCaptured" + File.separator + DateUtil.getDateString(new Date(), "yyyy-MM-dd"), fileName = "faceImage" + faceCaptured.getId() + ".jpg";
        ImgUtil.generateBase64Image(jsonObject.getString("faceImage"), upload + faceImagePath, fileName);
        faceCaptured.setFaceImage(faceImagePath + File.separator + fileName);

        String imagePath = File.separator + "faceCaptured" + File.separator + DateUtil.getDateString(new Date(), "yyyy-MM-dd"), imageFileName = "image" + faceCaptured.getId() + ".jpg";
        ImgUtil.generateBase64Image(jsonObject.getString("image"), upload + imagePath, imageFileName);
        faceCaptured.setImage(imagePath + File.separator + imageFileName);

        return faceCapturedClient.insert(faceCaptured);
    }

    /**
     * 语音数据同步
     *
     * @param syncListPojo
     * @return
     */
    @PostMapping("/speech")
    public Result speech(@RequestBody SyncListPojo<Speech> syncListPojo, HttpServletRequest request) {

        List<Speech> speeches = syncListPojo.getData();
        if (null == speeches || speeches.isEmpty()) {
            return Result.fail("同步数据为空!");
        }

        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }

        for (Speech speech : speeches) {

            if (StringUtil.isEmpty(speech.getNumbers())) {
                return Result.fail(JSON.toJSONString(speech) + "numbers不能为空");
            } else if (StringUtil.isEmpty(speech.getCreateDate())) {
                return Result.fail(JSON.toJSONString(speech) + "createDate不能为空");
            } else if (StringUtil.isEmpty(speech.getSpeechType())) {
                return Result.fail(JSON.toJSONString(speech) + "speechType不能为空");
            } else if (StringUtil.isEmpty(speech.getSpeechContent())) {
                return Result.fail(JSON.toJSONString(speech) + "speechContent不能为空");
            }

            speech.setId(StringUtil.getUUID());
            speech.setUserId(current.getUserId());
            speech.setUserName(current.getUserName());
            speech.setLocationId(current.getLocationId());
            speech.setLocationName(current.getLocationName());
            speech.setDeviceId(current.getId());
            speech.setDeviceName(current.getName());
        }

        return Result.success(speechClient.inserts(speeches), "同步成功!");
    }

    /**
     * 门口客流数据同步
     *
     * @param syncListPojo
     * @return
     */
    @PostMapping("/customersDoorway")
    public Result customersDoorway(@RequestBody SyncListPojo<CustomersDoorway> syncListPojo, HttpServletRequest request) {

        List<CustomersDoorway> customersDoorways = syncListPojo.getData();
        if (null == customersDoorways || customersDoorways.isEmpty()) {
            return Result.fail("同步数据为空!");
        }

        UserDevices current = (UserDevices) request.getAttribute(UserDeviceService.CurrentDevice);
        if (null == current) {
            return Result.fail("设备不可用!");
        }

        for (CustomersDoorway customersDoorway : customersDoorways) {

            if (StringUtil.isEmpty(customersDoorway.getNumbers())) {
                return Result.fail(JSON.toJSONString(customersDoorway) + "numbers不能为空");
            } else if (StringUtil.isEmpty(customersDoorway.getCreateDate())) {
                return Result.fail(JSON.toJSONString(customersDoorway) + "createDate不能为空");
            } else if (StringUtil.isEmpty(customersDoorway.getCameraId())) {
                return Result.fail(JSON.toJSONString(customersDoorway) + "cameraId不能为空");
            } else if (StringUtil.isEmpty(customersDoorway.getCameraName())) {
                return Result.fail(JSON.toJSONString(customersDoorway) + "cameraName不能为空");
            }

            customersDoorway.setId(StringUtil.getUUID());
            customersDoorway.setUserId(current.getUserId());
            customersDoorway.setUserName(current.getUserName());
            customersDoorway.setLocationId(current.getLocationId());
            customersDoorway.setLocationName(current.getLocationName());
            customersDoorway.setDeviceId(current.getId());
            customersDoorway.setDeviceName(current.getName());
        }

        return Result.success(customersDoorwayClient.inserts(customersDoorways), "同步成功!");
    }
}
